/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 * \file     Icu_Ip_Xtrg.c                                                                              *
 * \brief    This file mainly contains the definition of xtrg register operation                        *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/08/18     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif


/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/

/* icu-xtrg self file */
#include "Icu_Ip_Xtrg.h"
/* register operation file */
#include "RegHelper.h"
/* etimer resigter address file */
#include "Icu_Register.h"
/* critical section protection file */
#include "SchM_Icu.h"

/********************************************************************************************************
 *                                      Static variables                                                *
 *******************************************************************************************************/
#if (STD_ON == ICU_XTRG_CHANNEL_ENABLE)
/* xtrg module base address information */
static const uint32 Icu_Ip_XtrgBase[XTRG_MODULE_NUMBER] = {APBMUX_XTRG1_BASE,
                                                           APBMUX_XTRG2_BASE};

/********************************************************************************************************
 *                                      External Function                                               *
 *******************************************************************************************************/
/* memap information */
#define ICU_START_SEC_CODE
/** Traceability       : SWSR_ICU_004 */
#include "Icu_MemMap.h"

/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * \brief This function initializes the channel and set the xtrg hardware
 *        registers
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_XtrgChannelInit(
 *                                                  const Icu_XtrgChannelConfigType* xtrgChanConfigPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgChanConfigPtr - pointer to xtrg channel configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function initializes the channel and set the etimer
 *                      hardware registers
 * \endverbatim
 * Traceability       : SWSR_ICU_034 SWSR_ICU_035 SWSR_ICU_037
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgChannelInit(const Icu_XtrgChannelConfigType* xtrgChanConfigPtr)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    Std_ReturnType retVal = E_OK;
    uint32 pollUpd;
    uint32 pollTime = 0UL;
    Icu_XtrgHwChannel xtrgChannel;
    Icu_XtrgHwModule xtrgModule;
    Icu_XtrgHwChannel xtrgDualChannel;
    Icu_MeasurementModeType measureMode;
#if (STD_ON == ICU_GET_INPUTSTATE_API)
    uint8 xtrgLogChan;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
    if (NULL_PTR == xtrgChanConfigPtr)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        /* get the hardware channel */
#if (STD_ON == ICU_GET_INPUTSTATE_API)
        /* PRQA S 4461 1 */
        xtrgLogChan = xtrgChanConfigPtr->icuXtrgChannel;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
        xtrgChannel = xtrgChanConfigPtr->icuXtrgHwChan;
        xtrgModule = xtrgChanConfigPtr->icuXtrgHwModule;
        measureMode = xtrgChanConfigPtr->icuXtrgMeasureMode;
        /* set basic cnt information */
        if (FALSE == Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgBasicSet)
        {
            /* set xtrg g0 counter ovf value 0xffffff */
            REG_WRITE32(0xFFFFFFU, ICU_XTRG_CNT_G0_OVF(xtrgModule));
            /* update the overflow value flag (value: 1U) */
            REG_RMW32(ICU_XTRG_CNT_G0_CFG(xtrgModule),
                            ICU_XTRG_CNT_G0_OVF_UPD_START_BIT, 1U, 1U);
            /* delay a while unitl setting be synced,need
                (2*xtrg_clk+2*apb_clk) */
            pollUpd = (REG_READ32(ICU_XTRG_CNT_G0_CFG(xtrgModule)) &
                        ((uint32)0x01U << ICU_XTRG_CNT_G0_OVF_UPD_START_BIT));
            while (pollUpd != 0U)
            {
                /* time out control */
                pollUpd = (REG_READ32(ICU_XTRG_CNT_G0_CFG(xtrgModule)) &
                        ((uint32)0x01U << ICU_XTRG_CNT_G0_OVF_UPD_START_BIT));
                pollTime ++;
                if (pollTime > ICU_POLLING_TIME_OUT)
                {
                    retVal = E_NOT_OK;
                    break;
                } /* else not needed */
            }
            /* enable xtrg g0 counter */
            REG_WRITE32(1, ICU_XTRG_CNT_G0_ENABLE(xtrgModule));
            /* update basic information */
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgBasicSet = TRUE;
        }
        /* set the edge information */
        if (ICU_MODE_SIGNAL_MEASUREMENT == measureMode)
        {
            /* PRQA S 4342,4394,4521 2 */
            /* dual mode: cpt1_event generated by n+16 xtrg cpt module */
            xtrgDualChannel = (Icu_XtrgHwChannel)(xtrgChannel + 16U);
            /* PRQA S 0339 50 */
            /* update the cpt dual mode */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                            ICU_XTRG_CPT_CFG_DUAL_MODE_START_BIT, 1U, 1U, 1U);
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                            ICU_XTRG_CPT_CFG_DUAL_MODE_START_BIT, 1U, 1U, 1U);
            /* update the cpt0_event edge information */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U, ICU_FALLING_EDGE, 3U);
            /* update the cpt1_event edge information */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U, ICU_RISING_EDGE, 3U);
            /* update the counter select */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CNT_SEL_START_BIT, 2U, 0U, 3U);
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                    ICU_XTRG_CPT_CFG_CNT_SEL_START_BIT, 2U, 0U, 3U);
            /* update the dual mode input select */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CPT_DUAL_SEL_START_BIT, 1U, 0U, 1U);
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                    ICU_XTRG_CPT_CFG_CPT_DUAL_SEL_START_BIT, 1U, 1U, 1U);

        }
        else
        {
            /* update the cpt dual mode */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                            ICU_XTRG_CPT_CFG_DUAL_MODE_START_BIT, 1U, 0U, 1U);
            /* update the cpt trig edge information */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                        ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U,
                        xtrgChanConfigPtr->icuXtrgDefStartEdge, 3U);
            /* update the counter select */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CNT_SEL_START_BIT, 2U, 0U, 3U);
            /* update the dual mode input select */
            RMWREG32_RBC(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CPT_DUAL_SEL_START_BIT, 1U, 0U, 1U);
        }
#if (STD_ON == ICU_GET_INPUTSTATE_API)
        /* set the initial input status */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgChanlState[xtrgLogChan] = ICU_IDLE;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
    }
    return retVal;
}

#if (STD_ON == ICU_DEINIT_API)
/** *****************************************************************************************************
 * \brief This function de-initializes the channel and set the xtrg hardware
 *        registers
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_XtrgChannelDeInit(
 *                                                      const Icu_ChannelConfigType* xtrgChanConfigPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgChanConfigPtr - pointer to xtrg channel configuration
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function de-initializes the channel and set the etimer
 *                      hardware registers
 * \endverbatim
 * Traceability       : SWSR_ICU_034 SWSR_ICU_035 SWSR_ICU_037
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgChannelDeInit(const Icu_XtrgChannelConfigType* xtrgChanConfigPtr)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    Std_ReturnType retVal;
    Icu_XtrgHwChannel xtrgChannel;
    Icu_XtrgHwModule xtrgModule;
    Icu_XtrgHwChannel xtrgDualChannel;
    Icu_MeasurementModeType measureMode;
#if (STD_ON == ICU_GET_INPUTSTATE_API)
    uint8 xtrgLogChan;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
    if (NULL_PTR == xtrgChanConfigPtr)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        /* get the hardware channel */
#if (STD_ON == ICU_GET_INPUTSTATE_API)
        /* PRQA S 4461 1 */
        xtrgLogChan = xtrgChanConfigPtr->icuXtrgChannel;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
        xtrgChannel = xtrgChanConfigPtr->icuXtrgHwChan;
        xtrgModule = xtrgChanConfigPtr->icuXtrgHwModule;
        measureMode = xtrgChanConfigPtr->icuXtrgMeasureMode;

        /* #10 turn off capture channel */
        retVal = Icu_Ip_XtrgTurnOffCapture(xtrgModule, xtrgChannel);

        /* #20 restore the edge information */
        if (ICU_MODE_SIGNAL_MEASUREMENT == measureMode)
        {
            /* PRQA S 4342,4394,4521 2 */
            /* dual mode: cpt1_event generated by n+16 xtrg cpt module */
            xtrgDualChannel = (Icu_XtrgHwChannel)(xtrgChannel + 16U);
            /* PRQA S 0339 50 */
            /* restore the cpt dual mode */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                            ICU_XTRG_CPT_CFG_DUAL_MODE_START_BIT, 1U, 0U);
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                            ICU_XTRG_CPT_CFG_DUAL_MODE_START_BIT, 1U, 0U);
            /* restore the cpt0_event edge information */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U, ICU_RISING_EDGE);
            /* restore the cpt1_event edge information */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                    ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U, ICU_RISING_EDGE);
            /* restore the counter select */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CNT_SEL_START_BIT, 2U, 0U);
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                    ICU_XTRG_CPT_CFG_CNT_SEL_START_BIT, 2U, 0U);
            /* restore the dual mode input select */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CPT_DUAL_SEL_START_BIT, 1U, 0U);
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgDualChannel),
                    ICU_XTRG_CPT_CFG_CPT_DUAL_SEL_START_BIT, 1U, 0U);
        }
        else
        {
            /* restore the cpt dual mode */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                            ICU_XTRG_CPT_CFG_DUAL_MODE_START_BIT, 1U, 0U);
            /* restore the cpt trig edge information */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U, ICU_RISING_EDGE);
            /* restore the counter select */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CNT_SEL_START_BIT, 2U, 0U);
            /* restore the dual mode input select */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChannel),
                    ICU_XTRG_CPT_CFG_CPT_DUAL_SEL_START_BIT, 1U, 0U);
        }

        /* #30 restore basic cnt information */
        /* set xtrg g0 counter ovf value 0x000000 */
        REG_WRITE32(0x000000U, ICU_XTRG_CNT_G0_OVF(xtrgModule));
        /* restore the overflow value flag (value: 1U) */
        REG_RMW32(ICU_XTRG_CNT_G0_CFG(xtrgModule),
                        ICU_XTRG_CNT_G0_OVF_UPD_START_BIT, 1U, 1U);
        /* disable xtrg g0 counter */
        REG_WRITE32(0, ICU_XTRG_CNT_G0_ENABLE(xtrgModule));
        /* restore basic information */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgBasicSet = FALSE;
#if (STD_ON == ICU_GET_INPUTSTATE_API)
        /* restore the initial input status */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgChanlState[xtrgLogChan] = ICU_IDLE;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
    }
    return retVal;
}
#endif /* STD_ON == ICU_DEINIT_API */

/** *****************************************************************************************************
 * \brief This function turn On the xtrg capture channel
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_TurnOnCapture(
 *                                              Icu_XtrgHwChannel xtrgChan)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgChan - xtrg cpt cchannel module
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The setting result
 *
 * Description        : This function turn off the xtrg capture channel
 * \endverbatim
 * Traceability       : None
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgTurnOnCapture(Icu_XtrgHwModule xtrgModule, Icu_XtrgHwChannel xtrgChan)
{
    Std_ReturnType retVal = E_OK;
    uint32 convChan;
    if (MAX_XTRG_CAPTURE_MODULE <= (uint8)xtrgChan)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_05();
        /* PRQA S 1880 1 */
        if (HALF_XTRG_CAPTURE_MODULE > xtrgChan)
        {
            /* #10 turn on capture interrupt */
            REG_RMW32(ICU_XTRG_CPT_INT_STA_EN_0(xtrgModule), (uint32)xtrgChan, 1U, 1U);
            REG_RMW32(ICU_XTRG_CPT_INT_SIG_EN_0(xtrgModule), (uint32)xtrgChan, 1U, 1U);
        }
        else
        {
            /* PRQA S 4521 1 */
            convChan = (uint32)(xtrgChan - HALF_XTRG_CAPTURE_MODULE);
            /* #10 turn on capture interrupt */
            REG_RMW32(ICU_XTRG_CPT_INT_STA_EN_1(xtrgModule), convChan, 1U, 1U);
            REG_RMW32(ICU_XTRG_CPT_INT_SIG_EN_1(xtrgModule), convChan, 1U, 1U);
        }
        /* #20 turn on capture channel */
        REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChan), ICU_XTRG_CPT_CFG_CPT_EN_START_BIT, 1U, 1U);
        SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_05();
    }
    return retVal;
}

/** *****************************************************************************************************
 * \brief This function turn off the xtrg capture channel
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_TurnOffCapture(
 *                                              Icu_XtrgHwChannel xtrgChan)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgChan - xtrg cpt cchannel module
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The setting result
 *
 * Description        : This function turn off the xtrg capture channel
 * \endverbatim
 * Traceability       : None
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgTurnOffCapture(Icu_XtrgHwModule xtrgModule, Icu_XtrgHwChannel xtrgChan)
{
    Std_ReturnType retVal = E_OK;
    uint32 convChan;
    if (MAX_XTRG_CAPTURE_MODULE <= (uint8)xtrgChan)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_04();
        /* PRQA S 1880 1 */
        if (HALF_XTRG_CAPTURE_MODULE > xtrgChan)
        {
            /* #10 turn off capture interrupt */
            REG_RMW32(ICU_XTRG_CPT_INT_STA_EN_0(xtrgModule), (uint32)xtrgChan, 1U, 0U);
            REG_RMW32(ICU_XTRG_CPT_INT_SIG_EN_0(xtrgModule), (uint32)xtrgChan, 1U, 0U);
            /* #11 clear the interrupt status to avoid interrupt have already occured */
            REG_RMW32(ICU_XTRG_CPT_INT_STA_0(xtrgModule), (uint32)xtrgChan, 1U, 1U);
        }
        else
        {
            /* PRQA S 4521 1 */
            convChan = (uint32)(xtrgChan - HALF_XTRG_CAPTURE_MODULE);
            /* #10 turn off capture interrupt */
            REG_RMW32(ICU_XTRG_CPT_INT_STA_EN_1(xtrgModule), convChan, 1U, 0U);
            REG_RMW32(ICU_XTRG_CPT_INT_SIG_EN_1(xtrgModule), convChan, 1U, 0U);
            /* #11 clear the interrupt status to avoid interrupt have already occured */
            REG_RMW32(ICU_XTRG_CPT_INT_STA_1(xtrgModule), convChan, 1U, 1U);
        }
        /* #20 turn off capture channel */
        REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChan), ICU_XTRG_CPT_CFG_CPT_EN_START_BIT, 1U, 0U);
        SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_04();
    }
    return retVal;
}

/** *****************************************************************************************************
 * \brief This function sets the xtrg active edge information
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_XtrgSetActCondition(
 *                          Icu_XtrgHwChannel xtrgChan,
 *                          Icu_ActivationType activation,
 *                          boolean runSta)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgChan - xtrg cpt hardware module
 *                      activation - activation edge information
 *                      runSta - channel running status
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The setting result
 *
 * Description        : This function sets the xtrg active edge information
 * \endverbatim
 * Traceability       : SWSR_ICU_055
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgSetActCondition(Icu_XtrgHwModule xtrgModule, Icu_XtrgHwChannel xtrgChan, Icu_ActivationType activation, boolean runSta)
{
    Std_ReturnType retVal = E_OK;
    if (MAX_XTRG_CAPTURE_MODULE <= (uint8)xtrgChan)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        if (runSta == TRUE)
        {
            /* icu_xtrg: update the config need disable cpt_en first */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChan), ICU_XTRG_CPT_CFG_CPT_EN_START_BIT, 1U, 0U);
        }
        /* PRQA S 0339 2 */
        /* #20 set the activation edge information to xtrg */
        REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChan),
                        ICU_XTRG_CPT_CFG_TRIG_MODE_START_BIT, 2U, activation);
        if (runSta == TRUE)
        {
            /* icu_xtrg: need enable cpt_en after update the config */
            REG_RMW32(ICU_XTRG_CPT_CONFIG(xtrgModule, xtrgChan), ICU_XTRG_CPT_CFG_CPT_EN_START_BIT, 1U, 1U);
        }
    }
    return retVal;
}

#if (STD_ON == ICU_GET_INPUTSTATE_API)
/** *****************************************************************************************************
 * \brief This function gets input status
 *
 * \verbatim
 * Syntax             : Icu_InputStateType Icu_Ip_XtrgGetInputState(
 *                              Icu_HwModule tmrModule, Icu_HwChannel hwChannel)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : tmrModule - etimer hardware module
 *                      hwChannel - etimer hardware channel
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The input status in sigmeasurement mode
 *
 * Description        : This function gets input status
 * \endverbatim
 * Traceability       : SWSR_ICU_069 SWSR_ICU_071 SWSR_ICU_072 SWSR_ICU_073
 *******************************************************************************************************/
Icu_InputStateType Icu_Ip_XtrgGetInputState(uint8 xtrgLogCh)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_02();
    Icu_InputStateType inputSta = Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgChanlState[xtrgLogCh];
    /* #10 restore the input status */
    Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgChanlState[xtrgLogCh] = ICU_IDLE;
    SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_02();
    return inputSta;
}
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */

#if (STD_ON == ICU_SIGNALMEASUREMENT_API)
/** *****************************************************************************************************
 * \brief This function starts capture in signal measurement mode with xtrg
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_XtrgStartSigMeament(
 *                              uint8 xtrgLogCh, Icu_XtrgHwChannel xtrgChan)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgLogCh - xtrg logic channel index
 *                      xtrgChan - xtrg hardware capture module
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The setting result
 *
 * Description        : This function starts capture in signal measurement mode
 *                      with xtrg capture module
 * \endverbatim
 * Traceability       : SWSR_ICU_153 SWSR_ICU_155
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgStartSigMeament(Icu_XtrgHwModule xtrgModule, uint8 xtrgLogCh, Icu_XtrgHwChannel xtrgChan)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    Std_ReturnType retVal;
    if (MAX_XTRG_CAPTURE_MODULE <= (uint8)xtrgChan)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        /* #10 set the varibles to initial value */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh] = 0U;
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHasCptFlag[xtrgLogCh] = FALSE;
#if (STD_ON == ICU_GET_DUTYCYCLE_VALUES_API)
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgActiveTime[xtrgLogCh] = 0U;
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPeriodTime[xtrgLogCh] = 0U;
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHaveReadFlag[xtrgLogCh] = TRUE;
#endif /* STD_ON == ICU_GET_DUTYCYCLE_VALUES_API */
        /* #20 begin to turn on the capture channel */
        retVal = Icu_Ip_XtrgTurnOnCapture(xtrgModule, xtrgChan);
    }
    return retVal;
}

/** *****************************************************************************************************
 * \brief This function stops capture in signal measurement mode with xtrg
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_XtrgStopSigMeament(
 *                              uint8 xtrgLogCh, Icu_XtrgHwChannel xtrgChan)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgLogCh - xtrg logic channel index
 *                      xtrgChan - xtrg hardware capture module
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The setting result
 *
 * Description        : This function stops capture in signal measurement mode
 *                      with xtrg capture module
 * \endverbatim
 * Traceability       : SWSR_ICU_153 SWSR_ICU_155
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgStopSigMeament(Icu_XtrgHwModule xtrgModule, uint8 xtrgLogCh, Icu_XtrgHwChannel xtrgChan)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    Std_ReturnType retVal;
    if (MAX_XTRG_CAPTURE_MODULE <= (uint8)xtrgChan)
    {
        retVal = E_NOT_OK;
    }
    else
    {
        /* #10 begin to turn on the capture channel */
        retVal = Icu_Ip_XtrgTurnOffCapture(xtrgModule, xtrgChan);
        /* #10 set the varibles to initial value */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh] = 0U;
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHasCptFlag[xtrgLogCh] = FALSE;
#if (STD_ON == ICU_GET_DUTYCYCLE_VALUES_API)
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgActiveTime[xtrgLogCh] = 0U;
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPeriodTime[xtrgLogCh] = 0U;
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHaveReadFlag[xtrgLogCh] = TRUE;
#endif /* STD_ON == ICU_GET_DUTYCYCLE_VALUES_API */
    }
    return retVal;
}

#if (STD_ON == ICU_GET_DUTYCYCLE_VALUES_API)
/** *****************************************************************************************************
 * \brief This function gets dutycycle value in signal measurement mode
 *
 * \verbatim
 * Syntax             : Std_ReturnType Icu_Ip_XtrgGetDutyCycle(
 *                              uint8 xtrgLogCh,
 *                              Icu_DutyCycleType* dutyCyclePtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgLogCh - xtrg logic channel index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : dutyCyclePtr - pointer to a buffer where the results
 *
 * Return value       : The result status
 *
 * Description        : This function gets dutycycle value in signal measurement
 *                      mode
 * \endverbatim
 * Traceability       : SWSR_ICU_180 SWSR_ICU_181 SWSR_ICU_182 SWSR_ICU_183
 *                      SW_SM006
 *******************************************************************************************************/
Std_ReturnType Icu_Ip_XtrgGetDutyCycle(uint8 xtrgLogCh, Icu_DutyCycleType* dutyCyclePtr)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    Std_ReturnType retVal = E_OK;
    if ((NUM_OF_XTRG_CHANNEL <= xtrgLogCh))
    {
        retVal = E_NOT_OK;
    }
    else
    {
        /* #10 critical section protection */
        SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_00();
        /* #20 check the data has been read before */
        if (FALSE == Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHaveReadFlag[xtrgLogCh])
        {
            dutyCyclePtr->ActiveTime = Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgActiveTime[xtrgLogCh];
            dutyCyclePtr->PeriodTime = Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPeriodTime[xtrgLogCh];
            /* #30 restore the read flag */
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHaveReadFlag[xtrgLogCh] = TRUE;
        }
        else
        {
            dutyCyclePtr->ActiveTime = 0UL;
            dutyCyclePtr->PeriodTime = 0UL;
        }
        SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_00();
    }
    return retVal;
}
#endif /* STD_ON == ICU_GET_DUTYCYCLE_VALUES_API */

#if (STD_ON == ICU_GET_TIMEELAPSED_API)
/** *****************************************************************************************************
 * \brief This function gets signal time in signal measurement mode
 *
 * \verbatim
 * Syntax             : Icu_ValueType Icu_Ip_XtrgGetTimeElapsed(
 *                              uint8 xtrgLogCh)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgLogCh - xtrg logic channel index
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The signal time value
 *
 * Description        : This function gets signal time in signal measurement
 *                      mode
 * \endverbatim
 * Traceability       : SWSR_ICU_168 SWSR_ICU_169 SWSR_ICU_170 SWSR_ICU_171
 *                      SWSR_ICU_172 SWSR_ICU_173
 *******************************************************************************************************/
Icu_ValueType Icu_Ip_XtrgGetTimeElapsed(uint8 xtrgLogCh)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_02();
    Icu_ValueType signalTime = Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh];
    /* #10 restore the signal time value */
    Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh] = 0UL;
    SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_02();
    return signalTime;
}
#endif /* STD_ON == ICU_GET_TIMEELAPSED_API */
#endif /* STD_ON == ICU_SIGNALMEASUREMENT_API */

/** *****************************************************************************************************
 * \brief This function gets the interrupt status_0
 *
 * \verbatim
 * Syntax             : uint32 Icu_Ip_XtrgGetIntSta0(void)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : None
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The interrupt status0
 *
 * Description        : This function gets the interrupt status
 * \endverbatim
 * Traceability       : SWSR_ICU_190
 *******************************************************************************************************/
uint32 Icu_Ip_XtrgGetIntSta0(Icu_XtrgHwModule xtrgModule)
{
    /* #10 read the interrupt status */
    uint32 intStatus0 = REG_READ32(ICU_XTRG_CPT_INT_STA_0(xtrgModule));
    return intStatus0;
}

/** *****************************************************************************************************
 * \brief This function gets the interrupt status_1
 *
 * \verbatim
 * Syntax             : uint32 Icu_Ip_GetInterrupt(void)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : None
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The interrupt status1
 *
 * Description        : This function gets the interrupt status
 * \endverbatim
 * Traceability       : SWSR_ICU_190
 *******************************************************************************************************/
uint32 Icu_Ip_XtrgGetIntSta1(Icu_XtrgHwModule xtrgModule)
{
    /* #10 read the interrupt status */
    uint32 intStatus1 = REG_READ32(ICU_XTRG_CPT_INT_STA_1(xtrgModule));
    return intStatus1;
}

/** *****************************************************************************************************
 * \brief This function clear the interrupt status
 *
 * \verbatim
 * Syntax             : void Icu_Ip_XtrgClrInterrupt(Icu_XtrgHwChannel xtrgChan)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : tmrModule - etimer hardware module
 *                      hwChannel - etimer hardware channel
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The setting result
 *
 * Description        : This function clear the interrupt status
 * \endverbatim
 * Traceability       : SWSR_ICU_190
 *******************************************************************************************************/
void Icu_Ip_XtrgClrInterrupt(Icu_XtrgHwModule xtrgModule, Icu_XtrgHwChannel xtrgChan)
{
    uint32 convChan;
    /* PRQA S 1880 1 */
    if (HALF_XTRG_CAPTURE_MODULE > xtrgChan)
    {
        REG_WRITE32( 1UL << (uint32)xtrgChan, ICU_XTRG_CPT_INT_STA_0(xtrgModule));
    }
    else
    {
        /* PRQA S 4521 1 */
        convChan = (uint32)(xtrgChan - HALF_XTRG_CAPTURE_MODULE);
        REG_WRITE32( 1UL << convChan, ICU_XTRG_CPT_INT_STA_1(xtrgModule));
    }
}

/* memap information */
#define ICU_STOP_SEC_CODE
#include "Icu_MemMap.h"

/* memap information */
#define ICU_START_SEC_CODE_FAST
#include "Icu_MemMap.h"
#if (STD_ON == ICU_SIGNALMEASUREMENT_API)
/** *****************************************************************************************************
 * \brief This function calculates the signal time in sigmeasurement mode
 *
 * \verbatim
 * Syntax             : void Icu_Ip_XtrgSigMeaIrq(
 *                              const Icu_ChannelConfigType* channelConfigPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : None
 *
 * Parameters (in)    : xtrgLogCh - xtrg logic channel index
 *                      xtrgChan - xtrg hardware capture module
 *                      sigMeaType - signal measurement types
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function calculates the signal time in
 *                      sigmeasurement mode
 * \endverbatim
 * Traceability       : None
 *******************************************************************************************************/
void Icu_Ip_XtrgSigMeaIrq(Icu_XtrgHwModule xtrgModule, uint8 xtrgLogCh, Icu_XtrgHwChannel xtrgChan, Icu_SignalMeasurementPropertyType sigMeaType)
{
    uint32 coreId = Icu_Ip_GetCoreId();
    uint32 cpt0EventVal;
    uint32 cpt1EventVal;
    Icu_XtrgHwChannel dualChan;
    uint32 highTime;
    uint32 lowTime;

    if (FALSE == Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHasCptFlag[xtrgLogCh])
    {
        /* first captued value is useless */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHasCptFlag[xtrgLogCh] = TRUE;
        /* capture first cpt0_event value */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPreCptVal[xtrgLogCh] =
            REG_READ32(ICU_XTRG_CPT_VAL(xtrgModule, xtrgChan)) & 0xFFFFFFUL;
    }
    else
    {
        /* PRQA S 4342,4394,4521 2 */
        /* cpt1_event generated by n+16 xtrg cpt module */
        dualChan = (Icu_XtrgHwChannel)(xtrgChan + 16U);
        /* cpt0_event: capture falling edge */
        cpt0EventVal = REG_READ32(ICU_XTRG_CPT_VAL(xtrgModule, xtrgChan)) & 0xFFFFFFUL;
        /* cpt1_event: capture rising edge */
        cpt1EventVal = REG_READ32(ICU_XTRG_CPT_VAL(xtrgModule, dualChan)) & 0xFFFFFFUL;
        /* calculate the signal time value */
        if (cpt0EventVal > cpt1EventVal)
        {
            highTime = cpt0EventVal - cpt1EventVal;
        }
        else
        {
            /* xtrg counter width: 24bit */
            highTime = 0xFFFFFFUL - cpt1EventVal + cpt0EventVal;
        }
        if (cpt1EventVal > Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPreCptVal[xtrgLogCh])
        {
            lowTime = cpt1EventVal - Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPreCptVal[xtrgLogCh];
        }
        else
        {
            /* xtrg counter width: 24bit */
            lowTime = 0xFFFFFFUL - Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPreCptVal[xtrgLogCh] + cpt1EventVal;
        }
        /* update the pre captured value */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPreCptVal[xtrgLogCh] = cpt0EventVal;
        /* get signal time based on signal type*/
        switch (sigMeaType)
        {
        case ICU_LOW_TIME:
        {
            /* get the low time value */
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh] = lowTime;
            break;
        }
        case ICU_HIGH_TIME:
        {
            /* get the high time value */
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh] = highTime;
            break;
        }

        case ICU_PERIOD_TIME:
        {
            /* get the period time value */
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgSiglDuraVal[xtrgLogCh] = highTime + lowTime;
            break;
        }
#if (STD_ON == ICU_GET_DUTYCYCLE_VALUES_API)
        case ICU_DUTY_CYCLE:
        {
            /* get the duty and the period time value */
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgActiveTime[xtrgLogCh] = highTime;
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgPeriodTime[xtrgLogCh] = highTime + lowTime;
            Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgHaveReadFlag[xtrgLogCh] = FALSE;
            break;
        }
#endif /* STD_ON == ICU_GET_DUTYCYCLE_VALUES_API */
        default:
        {
            /* do nothing */
            break;
        }
        }
#if (STD_ON == ICU_GET_INPUTSTATE_API)
        /* update the input status */
        Icu_HandlerPtr[coreId]->icuXtrgHandlerConfig.icuXtrgChanlState[xtrgLogCh] = ICU_ACTIVE;
#endif /* STD_ON == ICU_GET_INPUTSTATE_API */
    }
}
#endif /* STD_ON == ICU_SIGNALMEASUREMENT_API */

/* memap information */
#define ICU_STOP_SEC_CODE_FAST
#include "Icu_MemMap.h"

#endif /* STD_ON == ICU_XTRG_CHANNEL_ENABLE */

#ifdef __cplusplus
}
#endif

/* End of file */
